﻿
namespace TLang.Values
{
    public class TType : Value
    {
        private static readonly TType T = new TType();
        public static readonly TType Bool = new TType(nameof(Bool));
        public static readonly TType Int = new TType(nameof(Int));
        public static readonly TType Float = new TType(nameof(Float));
        public static readonly TType String = new TType(nameof(String));
        public static readonly TType Vector = new TType(nameof(Vector));
        public static readonly TType Any = new TType(nameof(Any));
        public static readonly TType Void = new TType(nameof(Void));
        public static readonly TType Fun = new TType(nameof(Fun));
        public static readonly TType Record = new TType(nameof(Record));

        public readonly string Name;

        private TType() : base(null)
        {
            this.Name = "Type";
            base.Type = this;
        }

        protected TType(string name) : base(T)
        {
            this.Name = name;
        }

        public static bool Subtype(Value type1, Value type2, bool ret)
        {
            if (!ret && type2 == Any)
            {
                return true;
            }

            if (type1 is UnionType)
            {
                foreach (Value t in ((UnionType)type1).Values)
                {
                    if (!Subtype(t, type2, false))
                    {
                        return false;
                    }
                }
                return true;
            }
            else if (type2 is UnionType)
            {
                return ((UnionType)type2).Values.Contains(type1);
            }
            else
            {
                return type1.Equals(type2);
            }
        }
    }
}
